package com.ruoyi.web.controller.payApi;

import com.ruoyi.basedata.domain.Bank;
import com.ruoyi.basedata.domain.WalletKind;
import com.ruoyi.basedata.service.IBankService;
import com.ruoyi.basedata.service.IWalletKindService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.GoogleCodeUtil;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SignUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.financial.domain.MpFinancialSetting;
import com.ruoyi.financial.service.IMpFinancialSettingService;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.merchant.domain.*;
import com.ruoyi.merchant.service.IMpMerchantService;
import com.ruoyi.merchant.service.IMpMerchantWalletService;
import com.ruoyi.merchantAccount.domain.MerchantSetting;
import com.ruoyi.merchantAccount.service.IMerchantSettingService;
import com.ruoyi.payApi.PayTransReq;
import com.ruoyi.payApi.PayTransRsp;
import com.ruoyi.payApi.TestRsp;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.withdrawalParam.domain.PayCheckRsp;
import com.ruoyi.withdrawalParam.domain.WithdrawalCheckRsp;
import com.ruoyi.withdrawalParam.domain.WithdrawalReq;
import com.ruoyi.withdrawalParam.domain.WithdrawalRsp;
import net.sf.json.JSONObject;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;

/**
 * @Author: Mr.Lu
 * @Date: 2019/5/26 19:04
 */
@Controller
@RequestMapping("/payApi/test")
public class PayApiController extends BaseController {

    Logger log = LoggerFactory.getLogger(PayApiController.class);

    private String prefix = "payApi/test";

    @Autowired
    private IMpMerchantService merchantService;
    @Autowired
    private SysUserRoleMapper userRoleMapper;
    @Autowired
    private IMpFinancialSettingService financialSettingService;
    @Autowired
    private IMerchantSettingService merchantSettingService;
    @Autowired
    private IBankService bankService;
    @Autowired
    private IWalletKindService walletKindService;
    @Autowired
    private IMpMerchantWalletService merchantWalletService;


    // 交易下单请求URL
    @Value("${reqUrlConfig.merchantPay}")
    private String merchantPay;
    // 交易订单请求回调URL
    @Value("${reqUrlConfig.merchantSimulateNotifyPay}")
    private String merchantSimulateNotifyPay;
    // 支付订单查询URL - 外部
    @Value("${reqUrlConfig.merchantCheckPay}")
    private String merchantCheckPay;
    // 代付请求URL - 外部
    @Value("${reqUrlConfig.merchantWithdrawal}")
    private String merchantWithdrawal;
    // 代付订单查询URL - 外部
    @Value("${reqUrlConfig.merchantCheckWithdrawal}")
    private String merchantCheckWithdrawal;


    @GetMapping()
    public String statisticsPay(ModelMap mmap)
    {
        Long userId = ShiroUtils.getUserId();
        Long roleId = userRoleMapper.selectByUserId(userId);
        if (roleId.intValue() == 1){
            mmap.put("role",1);
        }
        if (roleId.intValue() == 6){
            mmap.put("userId",userId);
            mmap.put("role",6);
        }
        return prefix + "/test";
    }


    /**
     * 商户下拉框
     */
    @PostMapping("/merchantList")
    @ResponseBody
    public TableDataInfo list(MpMerchant mpMerchant)
    {
        startPage();
        List<MpMerchantRSP> list = merchantService.selectMpMerchantList(mpMerchant);
        return getDataTable(list);
    }



    /**
     * 商户钱包下拉框
     */
    @PostMapping("/merchantWalletList")
    @ResponseBody
    public TableDataInfo list(MpMerchantWallet mpMerchantWallet)
    {
        startPage();
        List<MpMerchantWalletVo> list = merchantWalletService.selectMpMerchantWalletList(mpMerchantWallet);
        return getDataTable(list);
    }



    @PostMapping("/bankList")
    @ResponseBody
    public TableDataInfo list(Bank bank)
    {
        startPage();
        List<Bank> list = bankService.selectBankList(bank);
        return getDataTable(list);
    }


    /**
     * 下单测试
     */
    @GetMapping("/orderPay")
    public String orderPay(@RequestParam("merchantId") Long merchantId, @RequestParam("service") String service, @RequestParam("accountBalanc") BigDecimal accountBalanc, ModelMap mmap){
        // 封装请求参数
        PayTransReq req = new PayTransReq();
        // 商户号
        MpMerchant merchant = merchantService.selectMpMerchantById(merchantId);
        req.setMch_id(merchant.getCode());
        // 通道编码
        req.setService(service);
        // 商户订单号
        String orderNumber = OrderUtils.createOrderCode(StringUtils.replace(UUID.randomUUID().toString(), "-", ""));
        req.setOut_trade_no(orderNumber);
        // 金额
        BigDecimal totalFee = accountBalanc.multiply(new BigDecimal(100));
        req.setTotal_fee(totalFee);
        // 商品描述
        req.setBody(merchant.getName() + ":的订单");
        // 回调地址
        req.setNotify_url(merchantSimulateNotifyPay);
        // 签名
        // 获取 sign
        String preString = req.toStringOther();
        String key = merchant.getSecretKey();
        String sign = SignUtil.getSignReq(preString, key);
        req.setSign(sign);
        // =========================请求接口======================
        log.info("请求的报文：" + req.allToString());
        TestRsp rsp = new TestRsp();
        // 请求的json数据
        rsp.setReq(req.allToString());
        String result = HttpUtils.sendPost(merchantPay, req.allToString(), false);
        if (StringUtils.isNotEmpty(result)) {
            JSONObject jsonObjectResult = JSONObject.fromObject(result);
            WithdrawalRsp withdrawalRsp = (WithdrawalRsp) net.sf.json.JSONObject.toBean(jsonObjectResult, WithdrawalRsp.class);
            if ("success".equals(withdrawalRsp.getCode())) {
                PayTransRsp payTransRsp = (PayTransRsp) net.sf.json.JSONObject.toBean(jsonObjectResult, PayTransRsp.class);
                // 封装响应结果，返回页面
                // 返回结果json数据
                String rsqJson = JSONObject.fromObject(payTransRsp).toString();
                rsp.setRsp(rsqJson);
                //  支付二维码url
                rsp.setQrCodeUrl(payTransRsp.getCode_url());
                mmap.put("withdrawalRsp",withdrawalRsp);
            }else {
                rsp.setRsp(result);
                mmap.put("withdrawalRsp",withdrawalRsp);
            }
        }
        mmap.put("payTransRsp",rsp);
        return prefix + "/payTransRsp";
    }



    /**
     * 交易状态查询（订单查询）
     * @param merchantId    商户号
     * @param orderNumber   订单号
     * @param mmap
     * @return              页面
     */
    @GetMapping("/orderPayCheck")
    public String orderPay(@RequestParam("merchantId") Long merchantId, @RequestParam("orderNumber") BigDecimal orderNumber, ModelMap mmap) {
        // 商户号
        MpMerchant merchant = merchantService.selectMpMerchantById(merchantId);
        // 请求数据
        String data = "mch_id=" + merchant.getCode() + "&out_trade_no=" + orderNumber;
        // 进行签名
        String sign = SignUtil.getSignReq(data, merchant.getSecretKey());
        data += "&sign=" + sign;
        log.info("请求的报文：" + data);
        String result = HttpUtils.sendPost(merchantCheckPay, data, false);
        // 返回页面的数据
        TestRsp rsp = new TestRsp();
        if (StringUtils.isNotEmpty(result)) {
            JSONObject jsonObjectResult = JSONObject.fromObject(result);
            WithdrawalRsp withdrawalRsp = (WithdrawalRsp) net.sf.json.JSONObject.toBean(jsonObjectResult, WithdrawalRsp.class);
            if ("success".equals(withdrawalRsp.getCode())) {
                PayCheckRsp payCheckRsp = (PayCheckRsp) net.sf.json.JSONObject.toBean(jsonObjectResult, PayCheckRsp.class);
                // 返回页面的数据
                // 请求报文
                rsp.setReq(data);
                String rsqJson = JSONObject.fromObject(payCheckRsp).toString();
                // 返回报文
                rsp.setRsp(rsqJson);

                mmap.put("withdrawalRsp",withdrawalRsp);
                mmap.put("status",payCheckRsp.getStatus());
            }else {
                mmap.put("withdrawalRsp",withdrawalRsp);
            }
        }
        mmap.put("payTransRsp",rsp);
        return prefix + "/queryTransInfoRsp";
    }


    /**
     * 代付测试
     * @param merchantWithdrawalPay 代付参数
     * @param mmap
     * @return
     */
    @GetMapping("/withDrawalPay")
    public String orderPay(@ModelAttribute MerchantWithdrawalPay merchantWithdrawalPay, ModelMap mmap) {
        Long userId = ShiroUtils.getUserId();
        Long roleId = userRoleMapper.selectByUserId(userId);
        // 封装请求参数
        WithdrawalReq withdrawalReq = makeReqParams(merchantWithdrawalPay);
        // 返回页面的数据
        TestRsp rsp = new TestRsp();
        log.info("请求的报文" + withdrawalReq.alltoString());
        // 请求报文
        rsp.setReq(withdrawalReq.alltoString());
        // 取款密码
        boolean password = false;
        // 谷歌验证
        boolean googleCode = false;
        // 管理员、四方支付系统_管理、四方支付系统_研发
        if (roleId.intValue() == 1){
            MpFinancialSetting setting = new MpFinancialSetting();
            List<MpFinancialSetting> mpFinancialSettings = financialSettingService.selectMpFinancialSettingList(setting);
            MpFinancialSetting mpFinancialSetting = mpFinancialSettings.get(0);
            if (StringUtils.isNotNull(mpFinancialSetting)) {
                password = merchantWithdrawalPay.getWithdrawalPassword().equals(mpFinancialSetting.getWithdrawalPassword());
                googleCode = GoogleCodeUtil.ValidCode(merchantWithdrawalPay.getGoogleCode(), mpFinancialSetting.getGoogleSecret());
            }
        }
        // MERCHANT_管理
        if (roleId.intValue() == 6) {
            MerchantSetting setting = new MerchantSetting();
            setting.setId(merchantWithdrawalPay.getMerchantId());
            List<MerchantSetting> merchantSettingList = merchantSettingService.selectMpMerchantList(setting);
            MerchantSetting merchantSetting = merchantSettingList.get(0);
            if (StringUtils.isNotNull(merchantSetting)) {
                password = merchantWithdrawalPay.getWithdrawalPassword().equals(merchantSetting.getWithdrawalPassword());
                googleCode = GoogleCodeUtil.ValidCode(merchantWithdrawalPay.getGoogleCode(), merchantSetting.getGoogleSecret());
            }
        }
        // 取款密码错误！
        if (!password) {
            mmap.put("error",0);
            mmap.put("check",0);
            mmap.put("payTransRsp",rsp);
            mmap.put("outTradeNum",withdrawalReq.getOut_trade_no());
            return prefix + "/withDrawalPayRsp";
        }
        // 验证码验证失败！
        if (!googleCode) {
            mmap.put("error",0);
            mmap.put("check",1);
            mmap.put("payTransRsp",rsp);
            mmap.put("outTradeNum",withdrawalReq.getOut_trade_no());
            return prefix + "/withDrawalPayRsp";
        }
        if (password && googleCode) {
            String result = HttpUtils.sendPost(merchantWithdrawal, withdrawalReq.alltoString(), false);
            if (StringUtils.isNotEmpty(result)) {
                JSONObject jsonObjectResult = JSONObject.fromObject(result);
                WithdrawalRsp withdrawalRsp = (WithdrawalRsp) net.sf.json.JSONObject.toBean(jsonObjectResult, WithdrawalRsp.class);
                // 返回报文
                String rsqJson = JSONObject.fromObject(withdrawalRsp).toString();
                rsp.setRsp(rsqJson);
                mmap.put("withdrawalRsp",withdrawalRsp);
            }else {
                WithdrawalRsp errorWithdrawalRsp = new WithdrawalRsp();
                errorWithdrawalRsp.setCode("error");
                errorWithdrawalRsp.setMsg("代付异常！");
                mmap.put("withdrawalRsp",errorWithdrawalRsp);
            }
            mmap.put("error",1);
            mmap.put("outTradeNum",withdrawalReq.getOut_trade_no());
            mmap.put("payTransRsp",rsp);
            return prefix + "/withDrawalPayRsp";
        }
        // 请求异常
        mmap.put("error",0);
        mmap.put("check",2);
        mmap.put("outTradeNum",withdrawalReq.getOut_trade_no());
        mmap.put("payTransRsp",rsp);
        return prefix + "/withDrawalPayRsp";
    }


    /**
     * 代付订单查询
     * @param merchantId    商户id
     * @param orderNumber   订单号
     * @param mmap
     * @return              订单查询页面
     */
    @GetMapping("/withdrawalOrderCheck")
    public String withdrawalOrderCheck(@RequestParam("merchantId") Long merchantId, @RequestParam("orderNumber") BigDecimal orderNumber, ModelMap mmap) {
        // 商户号
        MpMerchant merchant = merchantService.selectMpMerchantById(merchantId);
        // 请求数据
        String data = "mch_id=" + merchant.getCode() + "&out_trade_no=" + orderNumber;
        // 进行签名
        String sign = SignUtil.getSignReq(data, merchant.getSecretKey());
        data += "&sign=" + sign;
        log.info("请求的报文：" + data);
        String result = HttpUtils.sendPost(merchantCheckWithdrawal, data, false);
        // 返回页面的数据
        TestRsp rsp = new TestRsp();
        // 请求报文
        rsp.setReq(data);

        if (StringUtils.isNotEmpty(result)) {
            JSONObject jsonObjectResult = JSONObject.fromObject(result);
            WithdrawalRsp withdrawalRsp = (WithdrawalRsp) net.sf.json.JSONObject.toBean(jsonObjectResult, WithdrawalRsp.class);
            WithdrawalCheckRsp withdrawalCheckRsp = (WithdrawalCheckRsp) net.sf.json.JSONObject.toBean(jsonObjectResult, WithdrawalCheckRsp.class);
            String rsqJson = JSONObject.fromObject(withdrawalCheckRsp).toString();
            // 返回报文
            rsp.setRsp(rsqJson);
            // 请求成功
            mmap.put("reqStatus",0);
            mmap.put("withdrawalRsp",withdrawalRsp);
            mmap.put("withdrawalCheckRsp",withdrawalCheckRsp);
        }else {
            // 请求失败
            WithdrawalRsp withdrawalRsp = new WithdrawalRsp();
            withdrawalRsp.setCode("error");
            withdrawalRsp.setMsg("查询异常！请联系管理员！");
            mmap.put("reqStatus",1);
        }
        mmap.put("payTransRsp",rsp);
        return prefix + "/withDrawalCheckRsp";
    }





    /**
     * 封装代付请求参数
     */
    public WithdrawalReq makeReqParams(MerchantWithdrawalPay merchantWithdrawalPay){
        // 查询银行
        Bank bank = bankService.selectBankById(merchantWithdrawalPay.getBankId().intValue());
        WithdrawalReq withdrawal = new WithdrawalReq();
        // 商户号
        MpMerchant merchant = merchantService.selectMpMerchantById(merchantWithdrawalPay.getMerchantId());
        withdrawal.setMch_id(merchant.getCode());
        // 商户订单号
        String orderNumber = OrderUtils.createOrderCode(StringUtils.replace(UUID.randomUUID().toString(), "-", ""));
        withdrawal.setOut_trade_no(orderNumber);
        // 金额
        BigDecimal totalFee = merchantWithdrawalPay.getAccountBalance().multiply(new BigDecimal(100));
        withdrawal.setTotal_fee(totalFee);
        // 持卡人名称
        withdrawal.setBank_car_name(merchantWithdrawalPay.getBankAccountOwner());
        // 银行卡账户
        withdrawal.setBank_car_no(merchantWithdrawalPay.getBankAccountNo());
        // 开户银行代码
        withdrawal.setBank_type(bank.getCode());
        // 开户分行
        withdrawal.setBank_address(merchantWithdrawalPay.getBankBranch());
        // 支行名称
        withdrawal.setBranch(merchantWithdrawalPay.getBankSubBranch());
        // 开户省
        withdrawal.setBank_province(merchantWithdrawalPay.getBankProvince());
        // 开户市
        withdrawal.setBank_city(merchantWithdrawalPay.getBankCity());
        // 联行号
        if (StringUtils.isNotBlank(merchantWithdrawalPay.getBankUnionNo())) {
            withdrawal.setUnionBankNum(merchantWithdrawalPay.getBankUnionNo());
        }
        // 钱包类型
        WalletKind walletKind = walletKindService.selectWalletKindById(merchantWithdrawalPay.getWalletKindId().intValue());
        withdrawal.setWallet_type(walletKind.getCode());
        // 获取 sign
        String preString = withdrawal.toStringOther();
        String key = merchant.getSecretKey();
        String sign = SignUtil.getSignReq(preString, key);
        withdrawal.setSign(sign);
        return withdrawal;
    }
}
